package echiquier;

import modele.AbstractWhile;
import java.util.ArrayList;
import java.util.List;
import echiquier.Echiquier.Case;
import echiquier.Echiquier.Ligne;
import static echiquier.Echiquier.Case.*;
import static echiquier.Echiquier.Ligne.*;

/**
 *
 * @author me
 */
public final class Curseur extends AbstractWhile {

    private final static List<EtatCurseur> INSTANCE = new ArrayList<EtatCurseur>();
    private final Ligne ligneCourante;
    private Case caseAEtudier;

    public List<EtatCurseur> parcours() {
        return INSTANCE;
    }

    /**
     *Construction initialisant le INSTANCE à a1
     * fonction While (while) héritée de AbstractWhile<T>
     */
    protected Curseur() {
        this.caseAEtudier = a1;
        this.ligneCourante = nord;
        While();
    }

    /**
     *  Vérifie si toutes les cases ont été analysées
     * @return caseCourante == h8
     */
    @Override
    public boolean hasnext() {
        return caseAEtudier == h8;
    }

    /**
     * case à étudier next
     */
    @Override
    public void next() {
        caseAEtudier = Case.next();
        new CurseurDirection();
    }

    public final static class EtatCurseur {

        private final Ligne ligneCourante;
        private final Case caseCandidate;
        private final Case caseAEtudier;

        protected EtatCurseur(final Case caseAEtudier, final Ligne ligneCourante, final Case caseCandidate) {
            this.caseAEtudier = caseAEtudier;
            this.ligneCourante = ligneCourante;
            this.caseCandidate = caseCandidate;
        }

        public Case CaseAEtudier() {
            return caseAEtudier;
        }

        public Case CaseCandidate() {
            return caseCandidate;
        }

        public Ligne LigneCourante() {
            return ligneCourante;
        }
    }

    private final class CurseurDirection extends AbstractWhile {

        private Ligne ligneCourante;

        /**
         * INSTANCE de toutes les directions (16)
         * @param caseCourante
         */
        protected CurseurDirection() {
            While();
        }

        /**
         *
         * @return true si toutes les directions ont été analysées
         */
        @Override
        public boolean hasnext() {
            return Ligne.hasnext(ligneCourante);
        }

        /**
         * direction next
         */
        @Override
        public void next() {
            ligneCourante = Ligne.next();
            new CurseurLigne(caseAEtudier, ligneCourante);
        }
    }

    private final class CurseurLigne extends AbstractWhile {

        private final Case caseAEtudier;
        private final Ligne ligneCourante;
        private Case caseCandidate;

        /**
         *  INSTANCE de la direction courante
         * @param caseCourante
         * @param ligneCourante
         */
        protected CurseurLigne(final Case caseAEtudier, final Ligne ligneCourante) {
            this.caseCandidate = caseAEtudier;
            this.caseAEtudier = caseAEtudier;
            this.ligneCourante = ligneCourante;
            While();
        }

        /**
         * verifie si si le curseur sort de l'échiquier
         * @return true si le curseur sort de l'échiquier
         */
        @Override
        public boolean hasnext() {
//            assert echiquier != null;
            return Echiquier.hasnext(caseCandidate, ligneCourante);
        }

        /**
         * case next dans la direction en cours
         */
        @Override
        public void next() {
            caseCandidate = Echiquier.suivant(caseCandidate, ligneCourante);
            assert caseAEtudier != null && ligneCourante != null && caseCandidate != null;
            INSTANCE.add(new EtatCurseur(caseAEtudier, ligneCourante, caseCandidate));
        }
    }
}









